//
// DotNetNuke - http://www.dotnetnuke.com
// Copyright (c) 2002-2010
// by Perpetual Motion Interactive Systems Inc. ( http://www.perpetualmotion.ca )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//

using System;
using System.Diagnostics;
using System.Reflection;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Entities.Host;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Entities.Portals;
using DotNetNuke.UI.Modules;
namespace DotNetNuke.Services.Exceptions
{
	public static class Exceptions
	{
		public static ExceptionInfo GetExceptionInfo(Exception e)
		{
			ExceptionInfo objExceptionInfo = new ExceptionInfo();
			while (e.InnerException != null) {
				e = e.InnerException;
			}
			StackTrace st = new StackTrace(e, true);
			StackFrame sf = st.GetFrame(0);
			try {
				MemberInfo mi = sf.GetMethod();
				string res = mi.DeclaringType.Namespace + ".";
				res += mi.DeclaringType.Name + ".";
				res += mi.Name;
				objExceptionInfo.Method = res;
			} catch (Exception ex) {
				objExceptionInfo.Method = "N/A - Reflection Permission required";
			}
			if (!String.IsNullOrEmpty(sf.GetFileName())) {
				objExceptionInfo.FileName = sf.GetFileName();
				objExceptionInfo.FileColumnNumber = sf.GetFileColumnNumber();
				objExceptionInfo.FileLineNumber = sf.GetFileLineNumber();
			}
			return objExceptionInfo;
		}
		private static bool ThreadAbortCheck(Exception exc)
		{
			if (exc is System.Threading.ThreadAbortException) {
				System.Threading.Thread.ResetAbort();
				return true;
			} else {
				return false;
			}
		}
		public static void ProcessModuleLoadException(PortalModuleBase objPortalModuleBase, Exception exc)
		{
			ProcessModuleLoadException((Control)objPortalModuleBase, exc);
		}
		public static void ProcessModuleLoadException(PortalModuleBase objPortalModuleBase, Exception exc, bool DisplayErrorMessage)
		{
			ProcessModuleLoadException((Control)objPortalModuleBase, exc, DisplayErrorMessage);
		}
		public static void ProcessModuleLoadException(string FriendlyMessage, PortalModuleBase objPortalModuleBase, Exception exc, bool DisplayErrorMessage)
		{
			ProcessModuleLoadException(FriendlyMessage, (Control)objPortalModuleBase, exc, DisplayErrorMessage);
		}
		public static void ProcessModuleLoadException(Control ctrl, Exception exc)
		{
			if (ThreadAbortCheck(exc))
				return;
			ProcessModuleLoadException(ctrl, exc, true);
		}
		public static void ProcessModuleLoadException(Control ctrl, Exception exc, bool DisplayErrorMessage)
		{
			if (ThreadAbortCheck(exc))
				return;
			string friendlyMessage = Services.Localization.Localization.GetString("ErrorOccurred");
			IModuleControl ctrlModule = ctrl as IModuleControl;
			if (ctrlModule == null) {
				friendlyMessage = Services.Localization.Localization.GetString("ErrorOccurred");
			} else {
				string moduleTitle = Null.NullString;
				if (ctrlModule != null && ctrlModule.ModuleContext.Configuration != null) {
					moduleTitle = ctrlModule.ModuleContext.Configuration.ModuleTitle;
				}
				friendlyMessage = string.Format(Localization.Localization.GetString("ModuleUnavailable"), moduleTitle);
			}
			ProcessModuleLoadException(friendlyMessage, ctrl, exc, DisplayErrorMessage);
		}
		public static void ProcessModuleLoadException(string FriendlyMessage, Control ctrl, Exception exc)
		{
			if (ThreadAbortCheck(exc))
				return;
			ProcessModuleLoadException(FriendlyMessage, ctrl, exc, true);
		}
		public static void ProcessModuleLoadException(string FriendlyMessage, Control ctrl, Exception exc, bool DisplayErrorMessage)
		{
			if (ThreadAbortCheck(exc))
				return;
			PortalSettings _portalSettings = PortalController.GetCurrentPortalSettings();
			try {
				if (!Host.UseCustomErrorMessages) {
					throw new ModuleLoadException(FriendlyMessage, exc);
				} else {
					IModuleControl ctrlModule = ctrl as IModuleControl;
					ModuleLoadException lex = null;
					if (ctrlModule == null) {
						lex = new ModuleLoadException(exc.Message.ToString(), exc);
					} else {
						lex = new ModuleLoadException(exc.Message.ToString(), exc, ctrlModule.ModuleContext.Configuration);
					}
					Services.Log.EventLog.ExceptionLogController objExceptionLog = new Services.Log.EventLog.ExceptionLogController();
					objExceptionLog.AddLog(lex);
					if (DisplayErrorMessage) {
						PlaceHolder ErrorPlaceholder = null;
						if (ctrl.Parent != null) {
							ErrorPlaceholder = (PlaceHolder)ctrl.Parent.FindControl("MessagePlaceHolder");
						}
						if (ErrorPlaceholder != null) {
							ctrl.Visible = false;
							ErrorPlaceholder.Visible = true;
							ErrorPlaceholder.Controls.Add(new ErrorContainer(_portalSettings, FriendlyMessage, lex).Container);
						} else {
							ctrl.Controls.Add(new ErrorContainer(_portalSettings, FriendlyMessage, lex).Container);
						}
					}
				}
			} catch (Exception exc2) {
				ProcessPageLoadException(exc2);
			}
		}
		public static void ProcessPageLoadException(Exception exc)
		{
			PortalSettings _portalSettings = PortalController.GetCurrentPortalSettings();
			string appURL = DotNetNuke.Common.Globals.ApplicationURL();
			if (appURL.IndexOf("?") == Null.NullInteger) {
				appURL += "?def=ErrorMessage";
			} else {
				appURL += "&def=ErrorMessage";
			}
			ProcessPageLoadException(exc, appURL);
		}
		public static void ProcessPageLoadException(Exception exc, string URL)
		{
			if (ThreadAbortCheck(exc))
				return;
			PortalSettings _portalSettings = PortalController.GetCurrentPortalSettings();
			if (!Host.UseCustomErrorMessages) {
				throw new PageLoadException(exc.Message, exc);
			} else {
				PageLoadException lex = new PageLoadException(exc.Message.ToString(), exc);
				Services.Log.EventLog.ExceptionLogController objExceptionLog = new Services.Log.EventLog.ExceptionLogController();
				objExceptionLog.AddLog(lex);
				if (!String.IsNullOrEmpty(URL)) {
					if (URL.IndexOf("error=terminate") != -1) {
						HttpContext.Current.Response.Clear();
						HttpContext.Current.Server.Transfer("~/ErrorPage.aspx");
					} else {
						HttpContext.Current.Response.Redirect(URL, true);
					}
				}
			}
		}
		public static void LogException(ModuleLoadException exc)
		{
			Services.Log.EventLog.ExceptionLogController objExceptionLog = new Services.Log.EventLog.ExceptionLogController();
			objExceptionLog.AddLog(exc, Services.Log.EventLog.ExceptionLogController.ExceptionLogType.MODULE_LOAD_EXCEPTION);
		}
		public static void LogException(PageLoadException exc)
		{
			Services.Log.EventLog.ExceptionLogController objExceptionLog = new Services.Log.EventLog.ExceptionLogController();
			objExceptionLog.AddLog(exc, Services.Log.EventLog.ExceptionLogController.ExceptionLogType.PAGE_LOAD_EXCEPTION);
		}
		public static void LogException(SchedulerException exc)
		{
			Log.EventLog.ExceptionLogController objExceptionLog = new Log.EventLog.ExceptionLogController();
			objExceptionLog.AddLog(exc, Log.EventLog.ExceptionLogController.ExceptionLogType.SCHEDULER_EXCEPTION);
		}
		public static void LogException(SecurityException exc)
		{
			Log.EventLog.ExceptionLogController objExceptionLog = new Log.EventLog.ExceptionLogController();
			objExceptionLog.AddLog(exc, Log.EventLog.ExceptionLogController.ExceptionLogType.SECURITY_EXCEPTION);
		}
		public static void LogException(Exception exc)
		{
			Log.EventLog.ExceptionLogController objExceptionLog = new Log.EventLog.ExceptionLogController();
			objExceptionLog.AddLog(exc, Log.EventLog.ExceptionLogController.ExceptionLogType.GENERAL_EXCEPTION);
		}
		public static void ProcessSchedulerException(Exception exc)
		{
			Log.EventLog.ExceptionLogController objExceptionLog = new Log.EventLog.ExceptionLogController();
			objExceptionLog.AddLog(exc, Log.EventLog.ExceptionLogController.ExceptionLogType.SCHEDULER_EXCEPTION);
		}
		public static void LogSearchException(SearchException exc)
		{
			Log.EventLog.ExceptionLogController objExceptionLog = new Log.EventLog.ExceptionLogController();
			objExceptionLog.AddLog(exc, Log.EventLog.ExceptionLogController.ExceptionLogType.SEARCH_INDEXER_EXCEPTION);
		}
	}
}
